home *** CD-ROM | disk | FTP | other *** search
/ Your Choice 3 / Your Choice Software Collection 3.iso / prgmming / swag05 / archives.swg next >
Text File  |  1994-09-22  |  28KB  |  1 lines

  1. SWAGOLX.EXE (c) 1993 GDSOFT  ALL RIGHTS RESERVED 00004                                                                           1      05-25-9407:59ALL                      GARETH LEWIN             archive detection        SWAG9405            11     «Q   {ππ RS>    Can anyone tell me where to find some source dealing with archiveπ RS> detection?  I need to be able to determine what archival method was usedπ RS> on a file regardless of the extension..ππYep.ππBTW: I cut it out of a source I made it for. I should compile as is. you mightπhave to "USES" dos and/or CRT.ππ----------------------------= CUT HERE =-------------------------------------π}ππTypeπ     ArchiveType = (ARJ,ZIP,UC2,LZH,UNKNOWN);ππFunction GetArchiveType (Name : String) : Archivetype;πVar F : File;π    Buf: Word;π    StrBuf : String [3];πBeginπ  GetArchiveType := UNKNOWN;π  Assign (F,Name);π  FileMode := 0;π  Reset (F,1);π  If IoResult <> 0 Thenπ  Beginπ    Write ('Unable to access file - ');π    WriteLn (Name);π    Exit;π  End;π  BlockRead (F,Buf,2);π  If Buf = $EA60 Thenπ  Beginπ    GetArchiveType := ARJ;π    Close (f);π    Exit;π  End;π  If Buf = $4b50 Thenπ  Beginπ    GetArchiveType := ZIP;π    Close (f);π    Exit;π  End;π  If Buf = $4355 Thenπ  Beginπ    GetArchiveType := UC2;π    Close (f);π    Exit;π  End;π  BlockRead (F,StrBuf[1],3);π  StrBuf[0] := #3;π  If StrBuf = '-lh' Thenπ  Beginπ    GetArchiveType := LZH;π    Close (f);π    Exit;π  End;πEnd;ππ                                                                                         2      05-25-9407:59ALL                      MIKE COPELAND            arj files                SWAG9405            42     «Q   ππconstπ      BSize    = 4096;                                      { I/O Buffer Size }π      HMax     = 512;                                   { Header Maximum Size }π      DLM      = #32#179;π      HexDigits: array[0..15] of char = '0123456789ABCDEF';πtypeπ      MEDBUF       = array[1..4096] of char;πvarπ      DISKNUM      : Word;                     { Disk # - offset to Disk Info }π      WVN          : Word;                                 { Working Volume # }π      DIDX         : Word;                              { Files Display Index }π      VIDX         : Word;                            { Volumes Display Index }π      AIDX         : Word;                           { Archives Display Index }π      CIDX         : Word;                   { Compressed Files Display Index }π      ADX          : Word;                            { comPressed file Index }π      RES          : Word;                                   { Buffer Residue }π      N,P,Q        : Longint;π      ASZ,USZ,FSZ  : LongInt;              { Disk Available, Used, Free sizes }π      SEQNUM       : LongInt;                               { File Sequence # }π      C            : LongInt;                                 { Buffer Offset }π      FSize        : LongInt;                                     { File Size }π      CH, CH1      : char;π      DEVICE       : char;                                      { Disk Device }π      BIN,BOUT,π      BWORK        : ^MEDBUF;π      F            : File;π      SNAME        : String;π      DATE         : string[8];                  { formatted date as YY/MM/DD }π      TIME         : string[5];                  {     "     time as HH:MM    }π      X1,X2,X3,X4,π      X5,X6,X7,X8,π      X9,X10,X11,π      X12          : string;π      DISKNAME     : string[15];π      CMD          : string;                             { DOS Command string }π      INDENT       : string;                        { Report Indention string }π      GARB         : string[6];                        { extraneous device id }π      PRIORAN      : STR12;                              { Prior Archive Name }π      DirInfo      : SearchRec;                       { File name search type }π      SR           : SearchRec;π      DT           : DateTime;π      PATH         : PathStr;π      DIR          : DirStr;π      FNAME        : NameStr;π      EXT          : ExtStr;π      Regs         : Registers;π      Temp         : String[1];π      BUFF         : array[1..BSize] of Byte;π      IB           : InfoBuffer;π      S            : string[11];π      SNAME        : string[12];ππVar I,J,K : LongInt;π(**************************** ARJ Files Processing ***************************)πType  AHMain = record                                           { ARJ Headers }π                 HeadId  : Word;                                      { 60000 }π                 BHdrSz  : Word;                          { Basic Header Size }π                 FHdrSz  : Byte;                           { File Header Size }π                 AVNo    : Byte;π                 MAVX    : Byte;π                 HostOS  : Byte;π                 Flags   : Byte;π                 SVer    : Byte;π                 FType   : Byte;                 { must be 2 for basic header }π                 Res1    : Byte;π                 DOS_DT  : LongInt;π                 CSize   : LongInt;                         { Compressed Size }π                 OSize   : LongInt;                           { Original Size }π                 SEFP    : LongInt;π                 FSFPos  : Word;π                 SEDLgn  : Word;π                 Res2    : Word;π                 NameDat : array[1..120] of char;       { start of Name, etc. }π                 Res3    : array[1..10] of char;π               end;πVar ARJ1     : AHMain;πprocedure GET_ARJ_ENTRY;πbeginπ  FillChar(ARJ1,SizeOf(AHMain),#0); FillChar(BUFF,BSize,#0);π  Seek (F,C-1); BlockRead(F,BUFF,BSIZE,RES);        { read header into buffer }π  Move (BUFF[1],ARJ1,SizeOf(AHMain)); FSize := 0;π  with ARJ1 doπ    beginπ      if BHdrSz > 0 thenπ        beginπ          I := 1; SNAME := B40;π          while NameDat[I] > #0 do Inc (I);       { scan for end of file name }π          Move (NameDat[1],SNAME[1],I-1); SNAME[0] := Chr(I-1);π          FSize := BHdrSz+CSize;π          if FType = 2 then FSize := BHdrSz;π          if BHdrSz = 0 then FSize := 0;π        end;  { if }π    end;  { with }πend;  { GET_ARJ_ENTRY }ππprocedure DO_ARJ (FN : string);πbeginπ  Assign (F,FN); Reset (F,1); C := 1;π  GET_ARJ_ENTRY;                                        { Process file Header }π  while FSize > 0 doπ    beginπ      Inc(C,FSize+10); GET_ARJ_ENTRY;                         { get file info }π      if FSize > 0 thenπ        beginπ          with ARJ1 doπ            beginπ              FSplit (SNAME,DIR,FNAME,EXT);π              if Length(EXT) <= 0 then EXT := '    ';π              while Pos(#00,FNAME) > 0 do FNAME[Pos(#00,FNAME)] := ' ';π              F := Copy(FNAME+B40,1,8); E := Copy(EXT+'    ',1,4);π              SIZE := OSize; RTYPE := 4; D_T := DOS_DT;π              ANUM := ADX; VNUM := VDX;π            end;π        end;  { if }π    end;  { while }π  Close (F);πend;  { DO_ARJ }ππ                                                        3      05-25-9408:25ALL                      JOHN SHIPLEY             Zip Viewer               SWAG9405            119    «Q   {------8<-------------Snip---------------8<------------Snip------------8<-------}π{$I-}πUNIT zipviewu;ππ(*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\\/\/\/\/\/\/\/\*)π(* Unit : Zip View                    Date : March 23, 1994                  *)π(* By   : John Shipley                Ver  : 1.0                             *)π(*                                                                           *)π(* Credits : Steve Wierenga - ZIPV.PAS found in SWAG - Got me started on the *)π(*           zipviewu code since ZIPV.PAS was fairly easy to read unlike     *)π(*           some other code I had seen.                                     *)π(*                                                                           *)π(*           Tom Guinther - ZIPPER.PAS found in ZIPPER.ZIP (1989) available  *)π(*           on my BBS "The Brook Forest Inn 714-951-5282" This code helped  *)π(*           clarify many things. The zipper code is probably better than    *)π(*           this code and well documented.                                  *)π(*                                                                           *)π(*           PkWare's APPNOTE.TXT found in PKZ110.EXE                        *)π(*                                                                           *)π(* This unit is offered to the Public Domain so long as credit is given      *)π(* where credit is due. I accept NO liablity for what this code does to your *)π(* system or your friends or anyone elses. You have the code, so you can fix *)π(* it. If this code formats your hard drive and you loose your lifes work,   *)π(* then all I can say is "Why didn't you back it up?"                        *)π(*                                                                           *)π(* Purpose: To mimic "PKUNZIP -v <filename>" output. (v2.04g)                *)π(*          The code is pretty close to the purpose, but not perfect.        *)π(*                                                                           *)π(* Demo :                                                                    *)π(*                                                                           *)π(* PROGRAM zip_viewit;                                                       *)π(* USES DOS,CRT,zipviewu;                                                    *)π(* BEGIN                                                                     *)π(*   IF PARAMCOUNT<>0 THEN                                                   *)π(*     BEGIN                                                                 *)π(*       zipview(PARAMSTR(1));                                               *)π(*     END;                                                                  *)π(* END.                                                                      *)π(*/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\\/\/\/\/\/\/\/\*)ππINTERFACEππUSES DOS,CRT;ππPROCEDURE zipview(zipfile: STRING);ππIMPLEMENTATIONππCONST hexdigit : ARRAY[0..15] OF CHAR = '0123456789abcdef';ππFUNCTION hexbyte(b: byte): STRING;                        (* Byte to Hexbyte *)π  BEGINπ    hexbyte := hexdigit[b SHR 4]+hexdigit[b AND $f];π  END;ππFUNCTION hexlong(l: LONGINT): STRING;                  (* Longint to Hexlong *)π  VAR n : ARRAY[1..4] OF BYTE ABSOLUTE l;π  BEGINπ    hexlong := hexbyte(n[4])+hexbyte(n[3])+hexbyte(n[2])+hexbyte(n[1]);π  END;ππFUNCTION lenn(s: STRING): INTEGER;     (* Like LENGTH, but skips color codes *)π  VAR i,len : INTEGER;π  BEGINπ    len := LENGTH(s);π    i := 1;π    WHILE (i<=LENGTH(s)) DOπ      BEGINπ        IF (s[i] IN [#3,'^']) THENπ          IF (i<LENGTH(s)) THENπ            BEGINπ              DEC(len,2);π              INC(i);π            END;π        INC(i);π      END;π    lenn := len;π  END;ππFUNCTION mln(s: STRING; l: INTEGER): STRING;                 (* Left Justify *)π  BEGINπ    WHILE (lenn(s)<l) DO s := s+' ';π    IF (lenn(s)>l) THENπ      REPEATπ        s := COPY(s,1,LENGTH(s)-1)π      UNTIL (lenn(s)=l) OR (LENGTH(s)=0);π    mln := s;π  END;ππFUNCTION mrn(s: STRING; l: INTEGER): STRING;                (* Right Justify *)π  BEGINπ    WHILE lenn(s)<l DO s := ' '+s;π    IF lenn(s)>l THEN s := COPY(s,1,l);π    mrn := s;π  END;ππFUNCTION cstr(i: LONGINT): STRING;         (* convert integer type to string *)π  VAR c : STRING[16];π  BEGINπ    STR(i,c);π    cstr := c;π  END;ππFUNCTION tch(s: STRING): STRING;                          (* Ensure 2 Digits *)π  BEGINπ    IF (LENGTH(s)>2) THEN s := COPY(s,LENGTH(s)-1,2)π    ELSE IF (LENGTH(s)=1) THEN s := '0'+s;π    tch := s;π  END;ππFUNCTION b2attr(a,g: BYTE): STRING;                     (* Byte to Attribute *)π  VAR attr : STRING[5];π  BEGINπ    attr := '--w- ';π    IF (g AND 1)=1 THEN attr[5]:='*';                          (* Encrypted? *)π    IF (a AND 1)=1 THEN attr[3]:='r';                          (* Read Only? *)π    IF (a AND 2)=2 THEN attr[2]:='h';                             (* Hidden? *)π    IF (a AND 4)=4 THEN attr[1]:='s';                             (* System? *)π    IF (a AND 8)=8 THEN attr[4]:='?';                (* Unknown at this time *)π    b2attr := attr;π  END;ππFUNCTION w2date(d: WORD): STRING;                            (* Word to Date *)π  VAR s : STRING;π  BEGINπ    s := tch(cstr((d SHR 5) AND 15 ))+'-'+                          (* Month *)π         tch(cstr((d      ) AND 31 ))+'-'+                            (* Day *)π         tch(cstr(((d SHR 9) AND 127)+80));                          (* Year *)π    w2date := s;π  END;ππFUNCTION w2time(t: WORD): STRING;                            (* Word to Time *)π  VAR s : STRING;π  BEGINπ    s := tch(cstr((t SHR 11) AND 31))+':'+                           (* Hour *)π         tch(cstr((t SHR  5) AND 63));                             (* Minute *)π    w2time := s;π  END;ππPROCEDURE zipview(zipfile: STRING);                     (* View the ZIP File *)π  CONST lsig = $04034B50;                                 (* Local Signature *)π        csig = $02014b50;                               (* Central Signature *)π  TYPE lheader = RECORD                                      (* Local Header *)π                   signature  : LONGINT;      (* local file header signature *)π                   version,                                (* version mad by *)π                   gpflag,                          (* general purpose flags *)π                   compress,                           (* compression method *)π                   time,date  : WORD;         (* last mod file time and date *)π                   crc32,                                          (* crc-32 *)π                   csize,                                 (* compressed size *)π                   usize      : LONGINT;                (* uncompressed size *)π                   fnamelen,                              (* filename length *)π                   extrafield : WORD;                  (* extra field length *)π                 END;π       cheader = RECORD                                    (* Central Header *)π                   signature  : LONGINT;    (* central file header signature *)π                   version    : WORD;                     (* version made by *)π                   vneeded    : WORD;           (* version needed to extract *)π                   gpflag     : ARRAY[1..2] OF BYTE;(* general purpose flags *)π                   compress   : WORD;                  (* compression method *)π                   time       : WORD;                  (* last mod file time *)π                   date       : WORD;                  (* last mod file date *)π                   crc32      : LONGINT;                           (* crc-32 *)π                   csize      : LONGINT;                  (* compressed size *)π                   usize      : LONGINT;                (* uncompressed size *)π                   fnamelen   : WORD;                     (* filename length *)π                   extrafield : WORD;                  (* extra field length *)π                   fcl        : WORD;                 (* file comment length *)π                   dns        : WORD;                   (* disk number start *)π                   ifa        : WORD;            (* internal file attributes *)π                   efa        : ARRAY[1..4] OF BYTE;   (* external file attr *)π                   roolh      : LONGINT;  (* relative offset of local header *)π                 END;ππVAR z          : INTEGER;               (* Number of files processed counter *)π    totalu,                              (* Total bytes that were compressed *)π    totalc     : LONGINT;          (* result of total bytes being compressed *)π    hdr        : ^cheader;            (* temporary cental header file record *)π    f          : FILE;                                           (* file var *)π    s          : STRING;                          (* archive filename string *)π    percent    : BYTE;           (* Temporary var holding percent compressed *)π    numfiles   : WORD;                         (* Number of files in archive *)ππCONST comptypes : ARRAY[0..8] OF STRING[7] =            (* Compression Types *)π                  ('Stored ',                              (* Not Compressed *)π                   'Shrunk ',                                      (* Shrunk *)π                   'Reduce1',                                   (* Reduced 1 *)π                   'Reduce2',                                   (* Reduced 2 *)π                   'Reduce3',                                   (* Reduced 3 *)π                   'Reduce4',                                   (* Reduced 4 *)π                   'Implode',                                    (* Imploded *)π                   'NotSure',                        (* Unknown at this time *)π                   'DeflatN');                                   (* Deflated *)ππFUNCTION seekc(VAR f: FILE): BOOLEAN;π  VAR curpos  : LONGINT;                           (* current file position *)π      buf     : lheader;                   (* Temporary local header record *)π      ioerror : INTEGER;                       (* Temporary IOResult holder *)π      result  : WORD;                                   (* Blockread Result *)π  BEGINπ    seekc := FALSE;                                           (* init seekc *)π    curpos := 0;                              (* init current file position *)π    SEEK(f,0);                                        (* goto start of file *)π    BLOCKREAD(f,buf,SIZEOF(lheader),result);     (* Grab first local header *)π    ioerror := IORESULT;                                  (* Test for error *)π    WHILE (ioerror = 0) AND (buf.signature=lsig) DO (* Test if OK..continue *)π      BEGINπ        INC(numfiles);                         (* Increment number of files *)π        WITH buf DO                             (* Find end of local header *)π          curpos := FILEPOS(f)+fnamelen+extrafield+csize;π        SEEK(f,curpos);                         (* Goto end of local header *)π        BLOCKREAD(f,buf,SIZEOF(lheader),result);  (* Grab next local header *)π        ioerror := IORESULT;                              (* Test for error *)π      END;π      IF ioerror<>0 THEN EXIT;               (* If error then exit function *)π      IF (buf.signature=csig) THEN (* Did we find the first central header? *)π        BEGINπ          seekc := TRUE;                      (* Found first central header *)π          SEEK(f,curpos); (* Ensure we are at central headers file position *)π        END;π  END;ππ  VAR curpos : LONGINT;ππ  BEGINπ    numfiles := 0;      (* Counter of Number of Files to Determine When Done *)π    z        := 0;                   (* Counter of Number of Files Processed *)π    totalu   := 0;                      (* Total Bytes of Uncompressed Files *)π    totalc   := 0;                      (* Total Size after being Compressed *)π    NEW(hdr);        (* Dynamically Allocate Memory for a Temp Header Record *)π    ASSIGN(f,zipfile);                        (* Assign Filename to File Var *)π    {$I-}π    RESET(f,1);                                         (* Open Untyped File *)π    {$I+}π    IF IORESULT<>0 THEN                  (* If we get an error, exit program *)π      BEGINπ        WRITELN('Error - File not found.');π        HALT(253);π      END;π    IF NOT seekc(f) THEN (* Skip Local Headers and goto first Central Header *)π      BEGIN                       (* If we could not locate a Central Header *)π        CLOSE(f);                                      (* Close Untyped File *)π        WRITELN('Error - Corrupted or Not a ZIP File.');π        HALT(254);                                           (* Exit Program *)π      END;ππ    WRITELN(' Length  Method   Size  Ratio   Date    Time    CRC-32 '+π      ' Attr  Name');π    WRITELN(' ------  ------   ----- -----   ----    ----   --------'+π      ' ----  ----');π    REPEATπ      FILLCHAR(s,SIZEOF(s),#0);                         (* Clear Name String *)π      BLOCKREAD(f,hdr^,SIZEOF(cheader));                 (* Read File Header *)π      BLOCKREAD(f,MEM[SEG(s):OFS(s)+1],hdr^.fnamelen);  (* Read Archive Name *)π      s[0] := CHR(hdr^.fnamelen);                 (* Get Archive Name Length *)π      IF (hdr^.signature=csig) THEN                           (* Is a header *)π        BEGINπ          INC(z);                                  (* Increment File Counter *)π          WRITE(mrn(cstr(hdr^.usize),7));       (* Display Uncompressed Size *)π          WRITE(' '+mrn(comptypes[hdr^.compress],7));  (* Compression Method *)π          WRITE(mrn(cstr(hdr^.csize),8));         (* Display Compressed Size *)π          percent := ROUND(100.0-(hdr^.csize/hdr^.usize*100.0));π          WRITE(mrn(cstr(percent),4)+'% ');   (* Display Compression Percent *)π          WRITE(' '+w2date(hdr^.date)+' ');    (* Display Date Last Modified *)π          WRITE(' '+w2time(hdr^.time)+' ');    (* Display Time Last Modified *)π          WRITE(' '+hexlong(hdr^.crc32)+' ');       (* Display CRC-32 in Hex *)π          WRITE(b2attr(hdr^.efa[1],hdr^.gpflag[1]));   (* Display Attributes *)π          WRITELN(' '+mln(s,13));                (* Display Archive Filename *)π          INC(totalu,hdr^.usize);             (* Increment size uncompressed *)π          INC(totalc,hdr^.csize);               (* Increment size compressed *)π        END;π      SEEK(f,FILEPOS(f)+hdr^.extrafield+hdr^.fcl);π    UNTIL (hdr^.signature<>csig) OR EOF(f) OR (z=numfiles); (* No more Files *)π    WRITELN(' ------          ------  ---                                 '+π      ' -------');π    WRITE(mrn(cstr(totalu),7)+'         ');    (* Display Total Uncompressed *)π    WRITE(mrn(cstr(totalc),7)+' ');              (* Display Total Compressed *)π    WRITE((100-TotalC/TotalU*100):3:0,'%'+mrn(' ',34));   (* Display Percent *)π    WRITELN(mrn(cstr(z),7));                      (* Display Number of Files *)π    CLOSE(f);                                          (* Close Untyped File *)π    DISPOSE(hdr);                            (* Deallocate Header Var Memory *)π  END;ππEND.π                                            4      05-26-9407:31ALL                      SCOTT BAKER              Zip File Viewer          SWAG9405            42     «Q   unit ZipView;ππinterfaceπuses dos;ππtypeπ barray= array[1..8192] of byte;π ZipPtr=^ZipRec;π ZipRec= Recordπ          version_made: word;π          version_extr: word;π          flags: word;π          comp_method: word;π          last_mod_time: word;π          last_mod_date: word;π          crc_32: longint;π          compressed_size: longint;π          uncompressed_size: longint;π          fname_length: word;π          extra_length: word;π          comment_length: word;π          disk_num_start: word;π          internal_attr: word;π          external_attr: longint;π          rel_ofs: longint;π          name: string[12];π          Next: ZipPtr;π         end;π bptr = ^barray;πconstπ ZipMethod: array[0..9] of string[15] =π           ('stored   ',          'shrunk   ',       'reduced-1',π            'reduced-2',          'reduced-3',       'reduced-4',π            'imploded ',          'unknown  ',       'unknown  ',π            'unknown  ');ππvarπ totallength,totalsize,numfiles: longint;π firstzip: zipptr;π lineout: string;π outPtr: pointer;ππprocedure LoadZip(filename: string);πprocedure DisplayZip;πprocedure DisposeZip;ππimplementationππvarπ f: file of barray;π buffer: barray;π addr: longint;π bufptr: word;ππ{$F+}πProcedure CallProc;πinline($FF/$1E/OutPtr);π{$F-}ππFunction NextByte: byte;πvar i: integer;πbegin;π inc(addr);π inc(bufptr);π if bufptr=8193 then begin;π  {$I-}π  read(f,buffer);π  {$I+}π  i:=ioresult;π  bufptr:=1;π end;π nextbyte:=buffer[bufptr];πend;ππprocedure LoadZip(filename: string);πvarπ b: byte;π f2: file of byte;π fs: longint;π LastZip,Zip: ZipPtr;π Bytes: Bptr absolute zip;π a: integer;π sr: searchrec;πbegin;π firstzip:=nil;π{ assign(f2,filename);π reset(F2);π fs:=filesize(f2);π close(f2);}π findfirst(filename,anyfile,sr);π fs:=sr.size;π assign(f,filename);π reset(f);π addr:=0;π if fs>65535 then begin;π  seek(f,(fs div 8192)-4);π  addr:=addr+((fs div 8192)-4)*8192;π end;π {$I-}π read(f,buffer);π {$I+}π a:=ioresult;π bufptr:=0;π b:=nextbyte;π repeat;π  if b=$50 then begin;π   b:=nextbyte;π   if b=$4b then begin;π    b:=nextbyte;π    if b=$01 then begin;π     b:=nextbyte;π     if b=$02 then begin;π      new(zip);π      zip^.next:=nil;π      if firstzip=nil then firstzip:=zip else lastzip^.next:=zip;π      lastzip:=zip;π      for a:=1 to 42 do bytes^[a]:=nextbyte;π      zip^.name:='';π      for a:=1 to zip^.fname_length do zip^.name:=zip^.name+chr(nextbyte);π      b:=nextbyte;π     end;π    end;π   end;π  end else b:=nextbyte;π until addr>=fs;πend;ππprocedure OutLine(s: string);πbegin;π lineout:=s;π if OutPtr=NIL then writeln(s) else CallProc;πend;ππfunction format_date(date: word): string;πvarπ s,s2: string;π y,m,d: word;πbeginπ m:=(date shr 5) and 15;π d:=( (date      ) and 31);π y:=(((date shr 9) and 127)+80);π str(m,s);π while length(s)<2 do s:='0'+s;π s:=s+'-';π str(d,s2);π while length(s2)<2 do s2:='0'+s2;π s:=s+s2+'-';π str(y,s2);π while length(s2)<2 do s2:='0'+s2;π s:=s+s2;π format_date:=s;πend;ππfunction format_time(time: word): string;πvarπ s,s2: string;π h,m,se: word;πbeginπ h:=(time shr 11) and 31;π m:=(time shr  5) and 63;π se:=(time shl  1) and 63;π str(h,s);π while length(S)<2 do s:='0'+s;π s:=s+':';π str(m,s2);π while length(s2)<2 do s2:='0'+s2;π s:=s+s2;π format_time:=s;πend;ππprocedure DisplayHeader;πbegin;π OutLine('Filename      Length   Size     Method     Date      Time   Ratio');π OutLine('------------  -------  -------  ---------  --------  -----  -----');πend;ππprocedure DisplayFooter;πvarπ s,s2: string;π average: real;πbegin;π OutLine('------------  -------  -------                              -----');π average:=100-totalsize/totallength*100;π str(numfiles:12,s);π str(totallength:7,s2);π s:=s+'  '+s2+'  ';π str(totalsize:7,s2);π s:=s+s2+'                              ';π str(average:4:0,s2);π s:=s+s2+'%';π outline(s);πend;ππprocedure DisplayZip;πvarπ curzip: zipptr;π s,s2: string;πbegin;π numfiles:=0;π totallength:=0;π totalsize:=0;π DisplayHeader;π curzip:=firstzip;π while curzip<>nil do begin;π  s:=curzip^.name;π  while length(s)<14 do s:=s+' ';π  str(curzip^.uncompressed_size,s2);π  while length(s2)<7 do s2:=' '+s2;π  s:=s+s2+'  ';π  str(curzip^.compressed_size,s2);π  while length(s2)<7 do s2:=' '+s2;π  s:=s+s2+'  ';π  s:=s+ZipMethod[curzip^.comp_method]+'  ';π  s:=s+format_date(curzip^.last_mod_date)+'  '+format_time(curzip^.last_mod_time)+'  ';π  str(100-curzip^.compressed_size/curzip^.uncompressed_size*100:1:1,s2);π  s2:=s2+'%';π  while length(s2)<5 do s2:=' '+s2;π  s:=s+s2;π  Outline(s);π  totallength:=totallength+curzip^.uncompressed_size;π  totalsize:=totalsize+curzip^.compressed_size;π  inc(numfiles);π  curzip:=curzip^.next;π end;π if (numfiles=0) or (totallength=0) or (totalsize=0) then begin;π  outline('No valid file entries detected.');π end else begin;π  displayfooter;π end;πend;ππprocedure DisposeZip;πvarπ curzip,savezip: zipptr;πbegin;π curzip:=firstzip;π while curzip<>nil do begin;π  savezip:=curzip^.next;π  dispose(curzip);π  curzip:=savezip;π end;πend;ππbegin;π OutPtr:=Nil;πend.ππ{ --------------------------   CUT HERE -----------------------------}π{ TEST PROGRAM }ππuses zipview;ππvarπ s: string;πbegin;π write('File to Zip-View ? ');π readln(s);π LoadZip(s);π DisplayZip;π DisposeZip;πend.